//=======================================================
//AUTHOR: JEFF XL. ZHANG ARIZONA STATE UNIVERSITY
//ALL RIGHTS RESERVED  2008
//=======================================================

#pragma once
//#ifndef		//potential replacement for pragma once
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <math.h>
#include <vector>
#include <stdio.h>
#include <iostream>
#include "line.h"
#include "display.h"

using namespace std;

bool PRINT_DETECTION = 0;	


class Detection{
public:
	char *label;
	int method,aperture_size;
	double rho,theta,threshold;
	double param1, param2;
	double threshold_hough, threshold_canny_1, threshold_canny_2;
	vector<Line> DetectLine(const IplImage *img, char* label);
	Detection(char *label_in);
	Detection(int rho=1,double theta=CV_PI/180, double param1=100, double param2=50, double threshold_hough=70.0, double threshold_canny_1=200.0, double threshold_canny_2=300.0, int aperture_size=3);
	~Detection();
private:
	double _rho,_theta,_threshold;
	double _param1,_param2;
	double _threshold_hough, _threshold_canny_1, _threshold_canny_2;
	int _aperture_size;
};

Detection::Detection(char *label_in){
//	label = label_in;
	strcpy(label,label_in);
}

Detection::~Detection(){
//	delete label;
}

//Detection::Detection(int rho, double param1, double param2, double threshold_hough, double threshold_canny_1, double threshold_canny_2){
Detection::Detection(int rho, double theta, double param1, double param2, double threshold_hough, double threshold_canny_1, double threshold_canny_2, int apature_size){
	_rho = rho;
	_theta = CV_PI/180;
	_param1 = param1;
	_param2 = param2;
	_threshold_hough = threshold_hough;
	_threshold_canny_1 = threshold_canny_1;
	_threshold_canny_2 = threshold_canny_2;
	_aperture_size = 3;
}

vector<Line> Detection::DetectLine(const IplImage *img, char* label){
	//Definitions (local variables that needs to be defined to assist line detection)
//	Line line_buffer;
	vector<Line> lines_in_an_image;
	IplImage *img_gray = cvCreateImage(cvGetSize(img),8,1);
	IplImage *img_edge = cvCreateImage(cvGetSize(img),8,1);
	IplImage *img_edge_clr = cvCreateImage(cvGetSize(img),8,3);		//for demonstration purpose,Image is not part of output
	CvMemStorage *storage = cvCreateMemStorage(0);	// could be mem storage or cvMat 
	CvPoint pt1,pt2;
	CvSeq *lines = 0;
	char line_index[10];
	//Operations
	cvCvtColor( img,img_gray, CV_BGR2GRAY);
	cvCanny(img_gray, img_edge, _threshold_canny_1, _threshold_canny_2, 3 );
    cvCvtColor( img_edge, img_edge_clr, CV_GRAY2BGR );
	
	char edge_win[200];	
	sprintf(edge_win,"Edge_%s",label);
	Display(edge_win,img_edge);	
	
	CvFont textfont;
	cvInitFont(&textfont,CV_FONT_HERSHEY_COMPLEX_SMALL,0.7f,0.7f,.0,1,CV_AA);
	lines = cvHoughLines2(img_edge, storage, CV_HOUGH_PROBABILISTIC, _rho, _theta, _threshold_hough, _param1, _param2);
	
	for(int i = 0; i < lines->total; i++){
		CvPoint *line_buf = (CvPoint *)cvGetSeqElem(lines,i);
		
		//STORE LINES
		Line line_buffer(line_buf[0],line_buf[1]);
		lines_in_an_image.push_back(line_buffer);	//barely pushing lines into vector, no computation were done

		//HIGHLIGHT LINES
		cvLine(img_edge_clr,line_buf[0],line_buf[1],CV_RGB(255,0,0),1.5,8,0);
		
		//PRINT LINE INDEX
		lines_in_an_image[i].index = i;
		sprintf(line_index,"%d",i);
		cvPutText(img_edge_clr, line_index,cvPoint((line_buf[0].x+line_buf[1].x)/2,(line_buf[0].y+line_buf[1].y)/2),&textfont,CV_RGB(0,255,0));

	}	
	if(PRINT_DETECTION) cout<<"detected " << lines_in_an_image.size() <<" lines."<<endl;

	char line_win[200];	
	sprintf(line_win,"Line_%s",label);
	Display(line_win,img_edge_clr);

	cvReleaseImage(&img_gray);
	cvReleaseImage(&img_edge);
	cvReleaseImage(&img_edge_clr);
	cvReleaseMemStorage(&storage);
//	cvReleaseSeq(&lines);

	return lines_in_an_image;

}

